<template>
  <div class="merak-container-has-aside" curPageName="employee-list">
    <div class="merak-aside">
      <TreeNode
        :defTreeValue="state.organizeParams.org_department ?? state.organizeParams.org_company"
        @node-change="handleNodeChange"
      />
    </div>
    <div v-waterMarker v-loading="queueLoading" class="merak-card merak-container-has-search" curPageName="employee-list">
      <!-- 高级搜素组件 -->
      <SearchForm
        :auth="state.userAuth"
        :tableId="state.tableId"
        @add="state.add = true"
        @fast-search="handleFastSearch"
        @form-search="handleFormSearch"
      />
      <!-- 统计筛选组件 -->
      <MerakStatCard v-model="state.statValue" :data="state.statData" @change="handleStatChange" />
      <!-- 表格组件 -->
      <div class="merak-table-wrapper">
        <MerakXTable
          ref="tableRef"
          v-bind="tablePayload"
          :column-type="columnType"
          :batch-click="handleBatchClick"
          :handler-click="handleHanderClick"
          :query-columns="queryColumns"
          :query-data="queryData"
        >
          <!-- 员工详情插槽 -->
          <template #employee_details="{ row }">
            <el-popover
              :show-arrow="false"
              width="auto"
              placement="right-start"
              popper-style="min-width: 472px"
              @show="() => (row.__showCard = true)"
            >
              <template #reference>
                <el-button class="employee-button" link>{{ row.employee_name }}</el-button>
              </template>
              <!-- 员工详情信息卡片 -->
              <!-- 异步 -->
              <!-- <MerakUserCard
                :init="row.__showCard"
                :user-id="row.user_id"
                :user-auth="state.userAuth"
                @click="
                  key => router.push({ name: 'employeesInfo', query: { type: key, id: row.user_id, name: row.employee_name } })
                "
              /> -->
              <MerakUserCard
                :user-info="row"
                :user-auth="state.userAuth"
                @click="
                  key => router.push({ name: 'employeesInfo', query: { type: key, id: row.user_id, name: row.employee_name } })
                "
              />
            </el-popover>
          </template>
          <template #custom_handler="{ row }">
            <el-button type="primary" link @click="() => Object.assign(quickEditState, { visible: true, userId: row.user_id })">
              {{ $t("staff_list.quick_edit") }}
            </el-button>
          </template>
        </MerakXTable>
      </div>
    </div>
    <Transition name="fade" mode="out-in">
      <AddEmployee v-if="state.add" :nationOptions="state.nationOptions" @close="handleCloseAdd" />
    </Transition>
    <QuickEdit v-model="quickEditState.visible" :userId="quickEditState.userId" @close="handleCloseEdit" />
  </div>
</template>

<!-- render 函数需要设置为 jsx 语法 -->
<script setup lang="tsx" name="staffList">
import { getCurrentInstance, ref, reactive, computed, watch, onMounted } from "vue";

import { useRouter, useRoute } from "vue-router";

import { useGlobalStore } from "@/stores/modules/global";

import { ElButton, ElPopover } from "element-plus";

import MerakStatCard, { MerakStatCardInstance, MerakStatDataType } from "@/components/MerakStatCard";
import MerakXTable, { MerakXTableInstance, MerakXTableProps } from "@/components/MerakXTable";
import TreeNode from "@/views/personalManagement/a-components/oragnizationTree/index.vue";
import AddEmployee from "./components/AddEmployee.vue";

import QuickEdit from "./components/QuickEdit.vue";

import SearchForm from "./components/SearchForm.vue";

import MerakUserCard from "@/components/MerakUserCard";

import useLoading from "@/hooks/useLoading";

import { ResultEnum } from "@/enums/httpEnum";
import { UserAuthType, getUserAuth } from "@/api/modules/user";
import { Path, getTableColumns, getTableData } from "@/api/modules/table";
import { getStatistics, getDictOptions } from "@/api/modules/sysManage/personnel";

import { renderAge, renderTwelve } from "./formItems";

interface FilterType {
  action?: "enter" | "plan" | "form";
  params?: Record<string, any>;
  plan?: string | number;
  search?: string;
}

const currentInstance = getCurrentInstance();

// 路由示例
const router = useRouter();

// 页面级路由实例
const route = useRoute();

// 语言
const { language } = useGlobalStore();

// 使用队列 loading 管理初始化页面加载状态
const { queueLoading, queueId, queueReset } = useLoading();

// 表格实例
const tableRef = ref<MerakXTableInstance>();

// 页面配置数据
const state = reactive<{
  add?: boolean;
  organizeParams: {
    org_company?: number;
    org_department?: number;
  };
  filterOptions: Array<any>;
  filterParams: FilterType;
  statValue: string;
  statData: MerakStatDataType[][];
  statParams: Record<string, string | number>;
  tableId?: string;
  userAuth?: UserAuthType;
  nationOptions: Array<{ value: string | number; label: string }>;
}>({
  // 添加员工
  add: false,
  // 组织架构筛选值
  organizeParams: {
    org_company: !!route.query.org_company ? Number(route.query.org_company) : undefined,
    org_department: !!route.query.org_department ? Number(route.query.org_department) : undefined
  },
  // 高级搜索方案下拉选项
  filterOptions: [],
  // 高级搜索回调值
  filterParams: {},
  // 统计筛选激活项
  statValue: "",
  // 统计筛选数据
  statData: [],
  // 统计筛选激活后筛选数据
  statParams: {},
  // 国籍选项
  nationOptions: []
});

// 快速编辑数据
const quickEditState = reactive<{
  visible: boolean;
  userId?: string | number;
}>({
  visible: false
});

// 动态计算表格的外部筛选数据
const params = computed(() => {
  // 组织架构搜索
  const organizeValue = { ...state.organizeParams };
  // 统计搜索
  const statValue = { ...state.statParams };
  // 高级搜索
  const searchValue: Record<string, any> = {};
  switch (state.filterParams.action) {
    // 快速搜索
    case "enter":
      Object.assign(searchValue, { key_words: state.filterParams.search });
      break;
    // 方案搜索
    case "plan":
    case "form":
      const params: Record<string, any> = {};
      for (let [key, value] of Object.entries(state.filterParams.params ?? {})) {
        if (Array.isArray(value)) {
          if (!!value.length) {
            params[key] = value;
          }
          continue;
        }
        if (typeof value === "number" || !!value) {
          params[key] = value;
        }
      }
      Object.assign(searchValue, { ...params });
      break;
    default:
      break;
  }
  // 计算表格筛选数据
  return { ...organizeValue, ...statValue, ...searchValue };
});

// 表格配置属性
const tablePayload = reactive<MerakXTableProps>({
  // 列设置存储的数据对照值
  columnsByStore: [],
  // 最小列宽
  columnMinWidth: 120,
  // 表格行数据的唯一 key, 跟后端同步
  rowKey: "user_id",
  // 初始化的外部筛选数据
  params, // 同 params: parmas(computed的计算值)
  // 等待 params 获取数据
  awaitParams: true,
  // 展示特殊列(选中列/序号列/操作列等), 可通过传入对象形式扩展特殊列的渲染插槽, 例如
  // ["multiple", { type: 'handle', width: 200, slot: 'custom_slot_name' | ({ row })=> Component }]
  // columnType: [{ type: "handle", width: language === "zh" ? 120 : 180, slot: "custom_handler" }],
  // 导出权限判定
  enabledExport: true,
  // 批量操作选项
  batches: [{ type: "delete", text: "批量删除", color: "red" }],
  // 操作列选项
  handles: [{ type: "delete", text: "删除", color: "red" }]
});

// 表格操作列判定
const columnType = computed(() => {
  const types: MerakXTableProps["columnType"] = [];
  if (!!state.userAuth?.edit.show) {
    types.push({ type: "handle", width: language === "zh" ? 120 : 180, slot: "custom_handler" });
  }
  return types;
});

// 组织架构筛选
const handleNodeChange = ({ parent_id, org_id, level }: { parent_id?: number; org_id?: number; level: number }) => {
  const url = new URL(location.href);
  switch (level) {
    case 0:
      state.organizeParams = {};
      url.searchParams.delete("org_company");
      url.searchParams.delete("org_department");
      break;
    case 1:
      state.organizeParams = { org_company: org_id };
      url.searchParams.delete("org_department");
      if (typeof org_id === "number" || !!org_id) {
        url.searchParams.set("org_company", org_id.toString());
      }
      break;
    case 2:
      state.organizeParams = { org_company: parent_id, org_department: org_id };
      if (typeof parent_id === "number" || !!parent_id) {
        url.searchParams.set("org_company", parent_id.toString());
      }
      if (typeof org_id === "number" || !!org_id) {
        url.searchParams.set("org_department", org_id.toString());
      }

      break;
    default:
      break;
  }
  // 记录浏览器参数
  history.pushState({}, "", url);
};

// 统计筛选激活触发 table 数据请求
const handleStatChange: MerakStatCardInstance["onChange"] = params => {
  state.statParams = params;
};

// 高级搜索组件快速搜索触发事件
const handleFastSearch = (params: FilterType) => {
  state.filterParams = params;
};

// 高级搜索组件表单搜索触发事件
const handleFormSearch = (params: Record<string, any>) => {
  state.filterParams = { action: "form", params };
};

// 添加员工关闭触发事件
const handleCloseAdd = (refresh: boolean) => {
  if (refresh) {
    // 刷新队列loading
    queueReset();
    // 获取统计数据
    queryStatData();
    // 刷新表格
    tableRef.value?.reloadData();
  }
  state.add = false;
};

// 快速编辑保存成功后关闭事件
const handleCloseEdit = () => {
  // 刷新表格
  tableRef.value?.reloadData();
  quickEditState.visible = false;
};

/**
 * 表格批量操作事件触发
 * @param type 同 tablePayload.batched 子项的 type
 * @param mode 表格选中的模式  current: 当前页  all: 所有页
 * @param selectedKeys 表格当前页选中模式下选中的行数据 key 的集合, 表格所有页选中模式下未选中的行数据 key 的集合
 */
const handleBatchClick: MerakXTableInstance["batchClick"] = async ({ type, mode, selectedKeys }) => {
  switch (type) {
    case "delete":
      return {
        // 是否刷新表格, 默认 false, 可选参数
        refresh: false,
        // 是否重置表格(分页、排序), 默认 false, 可选参数
        reset: false
      };
    default:
      return;
  }
};

/**
 * 表格操作列事件触发
 * @param type 同 tablePayload.handles 子项的 type
 * @param params 表格操作数据, 可结构关于操作行的数据 { row, rowIndex, rowId }
 */
const handleHanderClick: MerakXTableInstance["handlerClick"] = async ({ type, params }) => {
  switch (type) {
    case "delete":
      // 是否刷新表格, 默认 false, 可选参数
      return true;
    default:
      return;
  }
};

// 获取统计数据
const queryStatData = async (init: boolean = false) => {
  // 初始化接口需要传入队列 loading 暴露的 id
  return getStatistics({ ...state.organizeParams }, queueId.value).then(({ code, data }) => {
    if (code == ResultEnum.SUCCESS) {
      state.statData = Object.values(data).map(item => item);
      if (!!state.statData?.[0]?.[0]) {
        state.statData[0][0].horizontal = true;
        if (init) {
          state.statValue = state.statData[0][0].key;
          state.statParams = { [state.statData[0][0].search_key]: state.statData[0][0].search_val };
        }
      }
    }
  });
};

// 获取表头数据
const queryColumns: MerakXTableInstance["queryColumns"] = async () => {
  // 初始化接口需要传入队列 loading 暴露的 id
  return getTableColumns(Path.personnel, queueId.value).then(({ code, data }) => {
    if (code == ResultEnum.SUCCESS) {
      // 存储表格ID
      state.tableId = data.table_id;
      // 克隆表头数据作为列设置的对照数据
      tablePayload.columnsByStore = JSON.parse(JSON.stringify(data.columns));
      return {
        ...data,
        columns: [...data.columns].map(column => {
          switch (column.field) {
            // 匹配列字段用于扩展自定义
            case "employee_name":
              // 设置最小宽度
              column.width = 180;
              // 固定列
              column.fixed = "left";
              // 扩展插槽悬浮员工姓名展开员工详情卡片
              column.slots = { default: "employee_details" };
              return column;
            case "job_no":
            case "hiredate":
              column.sortable = true;
              // column.slots = {
              //   default: ({ row }) => (!!row[column.field!] || row[column.field!] === 0 ? row[column.field!] : "-")
              // };
              return column;
            case "seniority":
              column.slots = {
                default: ({ row }) => {
                  let text = "";
                  const year = Math.floor(Number(row.seniority ?? 0) / 12);
                  const mouth = Number(row.seniority ?? 0) % 12;
                  if (year > 0) {
                    text += `${year}${currentInstance?.proxy?.$t("merak.year")}`;
                  }
                  if (mouth > 0) {
                    text += `${mouth > 9 ? "" : "0"}${mouth}${currentInstance?.proxy?.$t("merak.format_month")}`;
                  }
                  return text;
                }
              };
              return column;
            case "company_seniority":
              column.slots = {
                default: ({ row }) => (!!row?.hiredate ? renderAge(row?.hiredate) : "")
              };
              return column;
            case "age":
              column.slots = {
                default: ({ row }) => (!!row?.birthday ? renderAge(row?.birthday) : "")
              };
              return column;
            case "twelve":
              column.slots = {
                default: ({ row }) =>
                  !!row?.birthday ? currentInstance?.proxy?.$t(`staff_list.${renderTwelve(row?.birthday)}`) : ""
              };
              return column;
            default:
              // column.slots = {
              //   default: ({ row }) => (!!row[column.field ?? ""] || row[column.field ?? ""] === 0 ? row[column.field ?? ""] : "-")
              // };
              return column;
          }
        })
      };
    }
  });
};

/**
 * 获取表格数据
 * @param page 分页参数
 * @param sort 排序参数
 * @param sorts 多重排序参数
 * @param filters 表头筛选参数
 * @param from 外部由 tablePayload.params 传入的自定义参数
 */
const queryData: MerakXTableInstance["queryData"] = async ({ page, sort, sorts, from }) => {
  // 创建请求表格数据 post 的参数
  const params: Record<string, any> = {};
  // 如果有分页数据
  if (!!page) {
    Object.assign(params, { ...page });
  }
  // 如果有排序数据
  if (!!sort) {
    params.sort = sort.order === "desc" ? `-${sort.field}` : sort.field;
  }
  // 如果有自定义参数
  if (!!from) {
    for (let key of Object.keys(from)) {
      const item = from[key];
      if (typeof item === "number" || !!item) {
        params[key] = item;
      }
    }
  }
  // 初始化接口需要传入队列 loading 暴露的 id
  return getTableData(Path.personnel, params, queueId.value).then(({ code, data }) => {
    if (code == ResultEnum.SUCCESS) {
      return data.table_data;
    }
  });
};

// 初始化页面
const init = async () => {
  // 获取页面权限
  getUserAuth("staffList", queueId.value).then(({ code, data }) => {
    if (code == ResultEnum.SUCCESS) {
      state.userAuth = data;
      // tablePayload.enabledExport = !!data?.export.show;
    }
  });
  // 获取统计数据
  queryStatData(true);
  // 获取国籍选项
  getDictOptions({ key: "nationality" }).then(({ code, data }) => {
    if (code == ResultEnum.SUCCESS) {
      state.nationOptions = [...(data ?? [])].map(item => ({ value: item.key, label: item.value }));
    }
  });
};

// 监听初始化队列 loading 状态
watch(queueLoading, () => {
  if (queueLoading.value) {
    // 页面初始化队列 loading 时不允许 table 自动 loading
    tablePayload.loading = false;
  } else if ("loading" in tablePayload) {
    // 队列 loading 完成后清除 table 受控的 loading 属性
    delete tablePayload.loading;
  }
});

watch(
  () => state.organizeParams,
  () => {
    // 刷新队列loading
    queueReset();
    // 获取统计数据
    queryStatData();
  }
);

// 运行初始化
onMounted(() => init());
</script>

<style scoped lang="scss">
.fade-enter-active,
.fade-leave-active {
  transition: opacity 0.5s ease;
}

.fade-enter-from,
.fade-leave-to {
  opacity: 0;
}

.merak-container-has-aside {
  position: relative;
}

.employee-button {
  justify-content: flex-start;
  padding: 0;
  color: var(--merak-text-color);
  font-weight: 500;
  border-color: transparent !important;
  background-color: transparent !important;
}
</style>
